package com.neusoft.neuiotms.dcam.fixed.service.impl;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityNotFoundException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.neuiotms.common.constant.AHConstants;
import com.neusoft.neuiotms.common.service.SerialNumberService;
import com.neusoft.neuiotms.dcam.fixed.converter.AssetCodeRuleConverter;
import com.neusoft.neuiotms.dcam.fixed.dto.AssetCodeRuleDTO;
import com.neusoft.neuiotms.dcam.fixed.model.AssetCodeRule;
import com.neusoft.neuiotms.dcam.fixed.model.enums.AssetCodeConnector;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetCodeRuleRepository;
import com.neusoft.neuiotms.dcam.fixed.service.AssetCodeRuleService;

@Service
public class AssetCodeRuleServiceImpl implements AssetCodeRuleService {

    @Autowired
    private AssetCodeRuleConverter assetCodeRuleConverter;

    @Autowired
    private AssetCodeRuleRepository assetCodeRuleRepository;

    @Autowired
    private SerialNumberService serialNumberService;

    @Override
    public AssetCodeRuleDTO create(final AssetCodeRuleDTO dto) {
        final AssetCodeRule model = this.assetCodeRuleConverter.toModel(dto);
        this.assetCodeRuleRepository.save(model);
        return this.assetCodeRuleConverter.toDTO(model);
    }

    @Override
    public AssetCodeRuleDTO update(final Long id, final AssetCodeRuleDTO dto) {
        AssetCodeRule model;
        try {
            model = this.assetCodeRuleRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.assetCodeRuleConverter.toModel(dto);
        this.assetCodeRuleRepository.save(model);

        return this.assetCodeRuleConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {
        try {
            this.assetCodeRuleRepository.deleteById(id);
        } catch (final EmptyResultDataAccessException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }
    }

    @Override
    public List<AssetCodeRuleDTO> findAll() {
        final List<AssetCodeRule> models = this.assetCodeRuleRepository.findAll();
        return this.assetCodeRuleConverter.toListDTO(models);
    }

    @Override
    public AssetCodeRuleDTO details(final Long id) {
        final AssetCodeRule model;
        try {
            model = this.assetCodeRuleRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.assetCodeRuleConverter.toDTO(model);
    }

    @Override
    public String generateAssetCode(final String orgCode, final String locationCode, final String assetTypeCode) {
        final StringBuilder assetCode = new StringBuilder();

        final List<AssetCodeRule> models = this.assetCodeRuleRepository.findAll();
        final AssetCodeRule assetCodeRule = models.get(0);
        final List<String> fileds = assetCodeRule.getFileds();

        final AssetCodeConnector assetCodeConnector = assetCodeRule.getConnector();
        String connector = "";
        switch (assetCodeConnector) {
        case DOT:
            connector = ".";
            break;
        case HYPHEN:
            connector = "-";
            break;
        case UNDERLINE:
            connector = "_";
            break;
        default:
            connector = "";
            break;
        }

        final LocalDate localDate = LocalDate.now();

        final DateTimeFormatter patternYear6 = DateTimeFormatter.ofPattern("yyyyMM");
        final DateTimeFormatter patternYear4 = DateTimeFormatter.ofPattern("yyyy");
        final DateTimeFormatter patternYear2 = DateTimeFormatter.ofPattern("yy");
        final DateTimeFormatter patternMonth = DateTimeFormatter.ofPattern("MM");
        final DateTimeFormatter patternDay = DateTimeFormatter.ofPattern("dd");

        for (final String filedItem : fileds) {
            switch (filedItem) {
            case "Year":
                assetCode.append(localDate.format(patternYear2));
                break;
            case "Year4":
                assetCode.append(localDate.format(patternYear4));
                break;
            case "Year6":
                assetCode.append(localDate.format(patternYear6));
                break;
            case "Month":
                assetCode.append(localDate.format(patternMonth));
                break;
            case "Day":
                assetCode.append(localDate.format(patternDay));
                break;
            case "OrgId":
                assetCode.append(orgCode);
                break;
            case "AssetTypeCode":
                assetCode.append(assetTypeCode);
                break;
            case "LocationCode":
                assetCode.append(locationCode);
                break;
            }
            assetCode.append(connector);
        }
        assetCode.append(this.serialNumberService.generateSerialNumberByModelCode("ASSET_CODE"));
        return assetCode.toString();
    }

    /**
     * 1、KJ代表科技公司，所有资产前缀增加KJ标识。 2、第3位代表资产性质，1是固定资产，2是低值易耗品。
     * 3、第4～5位代表年份，2019年为19，2020年为20 4、第6～7位代表一级分类，房屋，车辆，计算机设备等
     * 5、第8～9位代表二级分类，安全设备，存储设备，主机设备等 6、第10～11位代表三级分类，路由器，交换机，防火墙等
     * 7、第12～15位代表资产编号，从0001～9999依次排列 举例说明：
     */
    @Override
    public String generateAssetCode(final String belongs, final String assetTypeCode, final Date purchaseDate,
            final String categories) {

        final SimpleDateFormat f = new SimpleDateFormat("yy");
        final String year =
                purchaseDate != null ? f.format(purchaseDate) : f.format(new Date());

        final StringBuilder code = new StringBuilder();
        // 前缀
        code.append(AHConstants.BELONG_SL_CODE.equalsIgnoreCase(belongs) ? "Z" : belongs.toUpperCase());
        // 资产性质
        code.append(categories);
        // 年份
        code.append(year);
        // 资产类型
        if (AHConstants.BELONG_KJ_CODE.equals(belongs)) {
            code.append(assetTypeCode.substring(3, 9));
        } else {
            code.append(assetTypeCode);
        }
        // 资产编号
        //code.append(this.serialNumberService.generateSerialNumberByModelCode(belongs.toUpperCase()));
        code.append(this.serialNumberService.generateSerialNumberByModelCode(assetTypeCode.toUpperCase()));
        return code.toString();
    }

}
